﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ImageProcessing.Forms
{
    public partial class NoiseDetection : Form
    {

        private static int x, y;
        private bool canMove = false;
        private static Rectangle cropRect;
        public static Point topLeft, downRight;
        Bitmap FirstBitmap;
        ImageStructure[,] imgstruct;
        HistogramChart histoNew;
        HistogramChart histoOld;

        public NoiseDetection(Bitmap bmp)
        {
            InitializeComponent();
            FirstBitmap = bmp;
            // DisplayedBitmap = Operations.CopyBitmap(FirstBitmap);
            pictureBox1.Image = FirstBitmap;
            imgstruct = Operations.ConvertBitmapToStructure(FirstBitmap);
            StartHistos();
            UpdatePcbLocation();
        }

        /// <summary>
        /// Handles the MouseMove event of the Image control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
        private void Image_MouseMove(object sender, MouseEventArgs e)
        {
            if (canMove)
            {
                UpdateRectangle(e);
                pictureBox1.Invalidate();
                this.Invalidate();
            }
        }

        /// <summary>
        /// Handles the MouseDown event of the Image control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
        private void Image_MouseDown(object sender, MouseEventArgs e)
        {

            canMove = true;
            cropRect = new Rectangle(e.X, e.Y, 0, 0);
            pictureBox1.Image = FirstBitmap;
            pictureBox1.Invalidate();
            this.Invalidate();

            x = e.X;
            y = e.Y;
        }

        /// <summary>
        /// Handles the MouseUp event of the Image control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
        private void Image_MouseUp(object sender, MouseEventArgs e)
        {
            canMove = false;
           // FadeCropping();

            histoNew.Updatehisto(new DImage(Operations.CropWithoutUpdate(imgstruct, topLeft, downRight), null, downRight.X - topLeft.X, downRight.Y - topLeft.Y, 2000));

            pictureBox1.Invalidate();
            this.Invalidate();
        }

        /// <summary>
        /// Updates the rectangle.
        /// </summary>
        /// <param name="e">The <see cref="System.Windows.Forms.MouseEventArgs"/> instance containing the event data.</param>
        private static void UpdateRectangle(MouseEventArgs e)
        {
            cropRect = new Rectangle(cropRect.Left, cropRect.Top, e.X - cropRect.Left, e.Y - cropRect.Top);
            topLeft.X = cropRect.Left;
            topLeft.Y = cropRect.Top;
            downRight.X = e.X;
            downRight.Y = e.Y;
        }

        /// <summary>
        /// Fades the cropping.
        /// </summary>
        private  void FadeCropping()
        {
            // ImageStructure[,] imgstruct = Operations.ConvertBitmapToStructure(FirstBitmap);
            //cropRect.Size = new Size(new Point(0, 0));
            //Thread t = null;
            //int rowsPerThread = FirstBitmap.Height / Environment.ProcessorCount;
            //Semaphore s = new Semaphore(1, 1000);
            //int minHeight = 0, maxHeight = 0;
            //for (int i = 1; i < Environment.ProcessorCount; i++)
            //{
            //    s.WaitOne();
            //    minHeight = i * rowsPerThread;
            //    maxHeight = (i + 1) * rowsPerThread;
            //    if (i == (Environment.ProcessorCount - 1))
            //    {
            //        t = new Thread(delegate() { CroppingImageSizeThreading(s, minHeight, DisplayedBitmap.Height,imgstruct); });
            //        t.Start();
            //        break;
            //    }

            //    t = new Thread(delegate() { CroppingImageSizeThreading(s, minHeight, maxHeight,imgstruct); });
            //    t.Start();
            //}

            //CroppingImageSizeThreading(s, 0, rowsPerThread, imgstruct);
            //Operations.CropWithoutUpdate(imgstruct, topLeft, downRight);

            //DisplayedBitmap = Operations.DisplayMatrix(imgstruct);
            //pictureBox1.Image = DisplayedBitmap;
            //histoNew.Updatehisto(new DImage(Operations.ConvertBitmapToStructure(DisplayedBitmap), null, DisplayedBitmap.Width, DisplayedBitmap.Height, 2000));

        }

        /// <summary>
        /// Croppings the image size threading.
        /// </summary>
        /// <param name="s">The s.</param>
        /// <param name="minHeight">Height of the min.</param>
        /// <param name="maxHeight">Height of the max.</param>
        /// <param name="image">The image.</param>
        private static void CroppingImageSizeThreading(Semaphore s, int minHeight, int maxHeight, ImageStructure[,] image)
        {
            s.Release();
            for (int i = minHeight; i < maxHeight; i++)
            {
                for (int j = 0; j < Main.ImageList[Main.CurrImage].Width; j++)
                {
                    if (j >= topLeft.X && j <= downRight.X && i >= topLeft.Y && i <= downRight.Y)
                    {
                        continue;
                    }

                    image[i, j].G = 0;
                    image[i, j].R = 0;
                }
            }
        }

        private void StartHistos()
        {
            histoNew = new HistogramChart();
            histoOld = new HistogramChart();
            Pnl_Histo1.Controls.Add(histoOld.HistoChart);
            Pnl_Histo1.Controls.Add(histoOld.CheckBlue);
            Pnl_Histo1.Controls.Add(histoOld.CheckRed);
            Pnl_Histo1.Controls.Add(histoOld.CheckGray);
            Pnl_Histo1.Controls.Add(histoOld.CheckGreen);
            Pnl_Histo2.Controls.Add(histoNew.HistoChart);
            Pnl_Histo2.Controls.Add(histoNew.CheckBlue);
            Pnl_Histo2.Controls.Add(histoNew.CheckRed);
            Pnl_Histo2.Controls.Add(histoNew.CheckGray);
            Pnl_Histo2.Controls.Add(histoNew.CheckGreen);
            Pnl_Histo1.Controls[1].BringToFront();
            Pnl_Histo1.Controls[2].BringToFront();
            Pnl_Histo1.Controls[3].BringToFront();
            Pnl_Histo1.Controls[4].BringToFront();
            Pnl_Histo2.Controls[1].BringToFront(); 
            Pnl_Histo2.Controls[2].BringToFront();
            Pnl_Histo2.Controls[3].BringToFront();
            Pnl_Histo2.Controls[4].BringToFront();
            histoOld.Updatehisto(new DImage(imgstruct, null, imgstruct.GetLength(1), imgstruct.GetLength(0), 2000));
        }

        private void Btn_Ok_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        public void UpdatePcbLocation()
        {
            pictureBox1.Location = new Point((panel3.Width / 2) - (pictureBox1.Width / 2), (panel3.Height / 2) - (pictureBox1.Height / 2));
            if (pictureBox1.Location.X < 0 && pictureBox1.Location.Y < 0)
            {
                pictureBox1.Location = new Point(0, 0);
            }
            else if (pictureBox1.Location.X < 0)
            {
                pictureBox1.Location = new Point(0, pictureBox1.Location.Y);
            }
            else if (pictureBox1.Location.Y < 0)
            {
                pictureBox1.Location = new Point(pictureBox1.Location.X, 0);
            }
        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Cross;
        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Default;
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            using (Pen pen = new Pen(Color.Red, 2))
            {
                e.Graphics.DrawRectangle(pen, cropRect);
            }
        }
    }
}
